'use strict';

const Controller = require('egg').Controller;
const config = require("../../../config/wx");
const crypto = require("crypto");
const { WxTransferStatusEnum, BalanceLogTypeEnum } = require("../../utils/enum");

class WithdrawPayController extends Controller {
    // 微信支付回调地址
    async decodePayNotify(resource) {
        try {
            const AUTH_KEY_LENGTH = 16;
            // ciphertext = 密文，associated_data = 填充内容， nonce = 位移
            const { ciphertext, associated_data, nonce } = resource;
            // 密钥
            const key_bytes = Buffer.from(config.key, 'utf8');
            // 位移
            const nonce_bytes = Buffer.from(nonce, 'utf8');
            // 填充内容
            const associated_data_bytes = Buffer.from(associated_data, 'utf8');
            // 密文Buffer
            const ciphertext_bytes = Buffer.from(ciphertext, 'base64');
            // 计算减去16位长度
            const cipherdata_length = ciphertext_bytes.length - AUTH_KEY_LENGTH;
            // upodata
            const cipherdata_bytes = ciphertext_bytes.slice(0, cipherdata_length);
            // tag
            const auth_tag_bytes = ciphertext_bytes.slice(cipherdata_length, ciphertext_bytes.length);
            const decipher = crypto.createDecipheriv(
                'aes-256-gcm', key_bytes, nonce_bytes
            );
            decipher.setAuthTag(auth_tag_bytes);
            decipher.setAAD(Buffer.from(associated_data_bytes));
            const output = Buffer.concat([
                decipher.update(cipherdata_bytes),
                decipher.final(),
            ]);
            // 解密后 转成 JSON 格式输出
            return JSON.parse(output.toString('utf8'));
        }
        catch (error){
            console.error('解密错误:', error);
            return null;
        }

    }

    /**
     * 微信支付回调
     * @param {Object} req - 请求对象，包含查询参数
     * url  https://qy.xxx.com/v1/payment/wx/success
     */
    async withdrawNotify() {
        const { ctx } = this;
            const result = ctx.request.body;
            // 记录日志
            this.ctx.logger.error('提现回调', {
                result: result
            });
            if (result.event_type === 'MCHTRANSFER.BILL.FINISHED') {
                // 解密微信支付成功后的订单信息
                const deInfo = await this.decodePayNotify(result.resource)
                this.ctx.logger.error('提现回调成功', {
                    deInfo
                });
                if (deInfo.state === WxTransferStatusEnum.SUCCESS) {
                    // 更新提现订单状态
                    await this.ctx.model.Business.BalanceRecord.update({
                        status: 1
                    }, {
                        where: {
                            out_bill_no: deInfo.out_bill_no,
                            type: BalanceLogTypeEnum.WITHDRAW
                        }
                    });
                    // 扣除手续费
                    this.ctx.service.business.balanceRecord.deductFee(deInfo.out_bill_no);
                } else {
                    // 更新提现订单状态
                    await this.ctx.model.Business.BalanceRecord.update({
                        status: -1,
                        state: deInfo.state,
                        fail_reason: deInfo.fail_reason
                    }, {
                        where: {
                            out_bill_no: deInfo.out_bill_no,
                            type: BalanceLogTypeEnum.WITHDRAW
                        }
                    });
                }
                // 支付成功
                this.ctx.success('success', 200);
            } else {
                // 支付失败
                this.ctx.error(500,'支付回调错误', 500);
            }
    }
}

module.exports = WithdrawPayController;
